import { profile } from '@/utils/decorators';
import { Logger } from '@/utils/logger';
import { declareTargetingAt } from './targetting';
import { TaskBase } from './TaskBase';
import { deserializeTask } from './taskmap';

export class CreepExtension extends Creep {
    /**
     * 把任务添加到任务队列，先进后出。
     */
    addTask(taskObject: TaskBase) {
        if (!this.memory.tasks) {
            this.memory.tasks = [];
        }
        this.memory.tasks.push(taskObject.serialize());
    }

    /**
     * 取出任务并运行，如果被冻结着就把计数器减一并不执行
     */
    @profile
    runTask() {
        // 检查是否还在 spawning
        if (this.spawning) {
            return ERR_BUSY;
        }
        // 检查是否在 suspend 的状态
        const suspendTimer = this.memory.suspendTimer;
        if (suspendTimer > 0) {
            // 显示 suspend timer
            this.say(`💤${this.memory.suspendTimer}`, true);
            this.memory.suspendTimer--; // 使显示一致
            return ERR_BUSY;
        }
        // 获取任务的原型数据
        while (this.memory.tasks?.length > 0) {
            const proto = this.memory.tasks?.[0];
            // 反序列化
            const object = deserializeTask(proto);
            // 检查是否有效
            if (object.shouldRun(this) === false) {
                this.memory.tasks.shift();  // 删除任务
                continue;
            }
            // 执行任务
            const ret = object.run(this);
            if (ret === OK) {
                // 执行结束，删除任务
                this.memory.tasks.shift();
            }
            return ret;
        }
        return ERR_NOT_FOUND;
    }

    declareTargeting() {
        if (this.memory.tasks && this.memory.tasks[0]) {
            const proto = this.memory.tasks?.[0];
            // 反序列化
            const object = deserializeTask(proto);
            if (object.shouldRun(this) === true) {
                // 添加到追踪
                declareTargetingAt(this, object.target);
            }
        }
    }

    makeSuspend(ticks = 1): void {
        this.memory.suspendTimer = Math.max(1, ticks);
    }

    isIdle(): boolean {
        // note! 这个坑好大，isIdle 与 isSuspended 无关！！！
        return this.memory.tasks === undefined || this.memory.tasks.length === 0;
    }

    isSuspended() {
        return this.memory.suspendTimer > 0;
    }
}